import logging
from datetime import datetime

from django.http import QueryDict, JsonResponse, HttpResponse
from django.utils.deprecation import MiddlewareMixin
from django.conf import settings

from gis.common.django_ext.views import PaginationResponse
from gis.common.exceptions import BizException
from gis.common.json import JsonEncoder

_LOGGER = logging.getLogger(__name__)


class ApiMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.DATA = QueryDict('')
        if request.method == 'GET':
            body = request.META['QUERY_STRING']
        else:
            if request.META.get('CONTENT_TYPE').startswith("multipart/form-data"):
                return
            else:
                body = request.body.decode()
        request.DATA = QueryDict(body)

    def process_exception(self, request, exception):
        if isinstance(exception, BizException):
            response = dict(
                status=exception.error_code.code,
                msg=exception.detail_message,
                timestamp=datetime.now(),
            )
        else:
            response = dict(
                status=-1,
                msg='内部错误，请联系管理员',
                timestamp=datetime.now(),
            )
        _LOGGER.exception('catched error %s in %s, uid:%s',
                          exception.__class__.__name__, request.path,
                          request.user_id if hasattr(request, 'user_id') else None)
        if not settings.DEBUG:
            return JsonResponse(response, encoder=JsonEncoder, status=500)

    def process_response(self, request, response):
        if isinstance(response, (dict, list, PaginationResponse)):
            wrap_data = dict(
                status=0,
                msg="OK",
                timestamp=datetime.now(),
            )
            if isinstance(response, PaginationResponse):
                response = dict(total=response.total, items=response.items, **response.kwargs)
            wrap_data['data'] = response
            return JsonResponse(wrap_data, encoder=JsonEncoder)
        elif isinstance(response, str):
            return HttpResponse(response)
        elif response is None:
            return HttpResponse('')
        else:
            return response
